分享有關 jQuery method chain 相關的 api 與 method chain 的基本知識
所謂的 method chain ,主要是一種操作上 API 設計,是用來讓開發者開發程式時少打幾個字,
並且透過 method chain 更方便開發以及開發時能連貫自己思緒的一種表達式。
這種作法需要在設計上下功夫, jQuery 也為此著墨很多。
以 jQuery 為例,我們熟悉的 method 用法,如以下範例
$("div").filter(":first")
.css("color","red")
.css("background","white")
.attr("name","hello");
如果換成非 chain ,想想看你需要寫多少程式碼。
var div = $("div"),
tempdiv;
tempdiv = div.filter(":first");
tempdiv.css("color","red");
tempdiv.css("backround","white");
寫起來是不是很囉唆?
要討論 jQuery 的 method chain ,得先從 method chain 的原型來討論,
基本上 method chain 基本實作方式,
就是把本來 setter 或一般操作等原本無回傳值的函式,
改成回傳操作者自己。
For example
var Obj = {
_valA:null,
_valB:null,
setA: function(val){
this._valA = val;
return this; //this is "Obj"
},
getA: function(){
return this._valA;
},
setB: function(val){
this._valB = val;
return this; //this is "Obj"
},
getB: function(){
return this._valB;
},
clearAll: function(){ //a general method
this._valA = null;
this._valB = null;
}
};
在有這樣的程式碼的狀況下,你就可以呼叫這些 method ,
因為他們回傳的就是 Obj 本身(或者同型態的物件),
所以就可以達到反覆調用 Obj 的 method 的效果。
這裡是一個範例
Obj.setA("hi").setB("hi2").clearAll()
.setA("A").setB("B");
alert(Obj.getA() +":"+ Obj.getB()); //will alert "A:B"
Runnable sample: http://jsfiddle.net/zCKRp/
單純就程式碼的實作你會發現「這裡沒有魔術」,
就只是單純的回傳值改變,從 undefined 變成調用者(caller) 本身。
通常也一定會有人會問,為什麼是 setter 而已,getter 呢?
像是 Obj.getB().getA() 這樣的寫法呢?
這樣當然不 work !
getB() 我們期待的是回傳「資料」,所以 getB() 已經要求要回傳數值,
當然就不能再用這資料做 method chain 。
那我們回頭過來說,jQuery 主要常用來作 method chain 用法的 api 有
find , filter, not , css setter , attr setter, data setter 等等等等。
所以我們又要回頭再看一次開頭提到的 jQuery 的範例:
$("div").filter(":first")
.css("color","red")
.css("background","white")
.attr("name","hello");
結束了嗎?
還沒!
因為 jQuery 的人用的人多,所以--怪--特別需求也多,
jQuery 的 method chain 上還有一些特殊功能。
我們最後要介紹的兩個相關函式跟操作用法,並且介紹為什麼會有這麼--奇怪--特別需求。
在這裡我們先列出來:
andSelf()
http://api.jquery.com/andSelf/
end()
http://api.jquery.com/end/
@ andSelf()
用法是當我們作一些操作 query 出不同的 data set 時,
有時候我希望把之前的集合也拿回來一起操作,我就會需要這東西。
舉例,假設我想要拿到這一個跟下一個,有一個常見的 combo是
$(selector).next().andSelf()
<div id="parent">
<div id="first">1</div>
<div >2</div>
<div >3</div>
<div >4</div>
</div>
<script>
$("#first") //此時為 [#first]
.next() //此時為 [div]
.andSelf() // 此時為 [#first,div]
.append(":get you.");
</script>
換成傳統寫法的話,大概就像是
<div id="parent">
<div id="first">1</div>
<div >2</div>
<div >3</div>
<div >4</div>
</div>
<script>
var item = $("#first"), //此時為 [#first]
newitem = item.next(); //此時為 [div]
newitem
.add(item) // 此時為 [#first,div]
.append(":get you.");
</script>
它會幫你把呼叫 andSelf 之前的最後一個不同集合加回當前集合,變成新的集合。
@ end()
他的功用則是讓你找回上一層的集合
舉例
<div id="parent">
<div id="first">1</div>
<div >2</div>
<div >3</div>
<div >4</div>
</div>
<script>
$("#first") //此時為 [#first]
.next() //此時為 [div]
.append(":get div")
.end() // 此時為 [#first] (之前最後一個集合是 #first )
.append(":get first.");
</script>
善用這些方法,基本上應該可以讓你寫程式寫得比較有趣一點,
method chain 雖然寫起來方便逗趣,但是可不要太依賴他喔!
確實的了解每個函式的回傳型態跟回傳值,
適當的組織程式碼跟排版,才是開發的不二法門。:)
今天在找簡化程式碼的方法,突然想到jQuery的method chain 方法,就找到TonyQ大大這篇,馬上就拿來用了,讓程式碼看上去優雅不少。